package com.rxt.thermopro.ui.fragment

import android.app.Activity
import android.app.ProgressDialog
import android.bluetooth.BluetoothGattCharacteristic
import android.content.Intent
import android.net.Uri
import android.os.Bundle
import android.provider.OpenableColumns
import android.util.Log
import android.view.View
import androidx.appcompat.app.AlertDialog
import androidx.core.content.ContextCompat
import androidx.lifecycle.Observer
import androidx.lifecycle.ViewModelProvider
import com.app.common.base.BaseFragment
import com.app.common.ex.toast
import com.rxt.ble.BleManager
import com.rxt.thermopro.R
import com.rxt.thermopro.app.LocalDataDao
import com.rxt.thermopro.ex.OtaFileType
import com.rxt.thermopro.ui.dialog.ProbeAlarmBottomDialog
import com.rxt.thermopro.ui.dialog.TempPreAlarmBottomDialog
import com.rxt.thermopro.viewmodel.BleMessageViewModel
import com.rxt.thermopro.viewmodel.TP960SettingViewModel
import kotlinx.android.synthetic.main.fragment_tp960_setting.*
import java.io.*
import java.util.*


class TP960SettingFragment : BaseFragment<TP960SettingViewModel>() {
    override fun layoutId(): Int {
        return R.layout.fragment_tp960_setting
    }

    companion object {
        private const val FILE_CHOOSER_REQUEST_CODE = 9999
        private const val ARG_ADDRESS = "address"

        fun newInstance(): TP960SettingFragment {
            return TP960SettingFragment()
        }

        fun newInstance(address: String): TP960SettingFragment {
            return TP960SettingFragment().apply {
                arguments = Bundle().apply {
                    putString(ARG_ADDRESS, address)
                }
            }
        }
    }

    private var mAddresses = ""
    private var currentOtaFileType: OtaFileType? = null

    // OTA file paths
    private var appPath = ""
    private lateinit var mBleViewModel: BleMessageViewModel
    private var dialog: AlertDialog? = null

    override fun initView(savedInstanceState: Bundle?) {
        mBleViewModel =
            ViewModelProvider(requireActivity()).get(BleMessageViewModel::class.java)
        mAddresses = arguments?.getString(ARG_ADDRESS, "") ?: ""
        switchNotice.isSelected = LocalDataDao.INSTANCE.isDisconnectNotice(mAddresses)
        switchAlarm.isSelected = LocalDataDao.INSTANCE.isAlarm(mAddresses)
        switchAlarmVibration.isSelected = LocalDataDao.INSTANCE.isAlarmVibration(mAddresses)

        setListener()

        val tempAlarmList = LocalDataDao.INSTANCE.getTempPreAlarmList()
        preAlarmType.text =
            tempAlarmList[LocalDataDao.INSTANCE.getTempPreAlarm(mAddresses)].alarmSimpleName

        mViewModel.getProbeAlarmList()

        mViewModel.probeAlarmList.observe(this, Observer {
            probe_1.text = it[LocalDataDao.INSTANCE.getProbeAlarm1(mAddresses)].ringName
        })

        mBleViewModel.otaUploadStatus.observeInFragment(this, Observer {
            if (it.isNotEmpty()) {
                it[mAddresses]?.let { item ->
                    if (item.second == 1) {
                        mViewModel.ota_mode = true
                        //OTA已开启
                        mViewModel.dfuMode("OTABEGIN")
                    } else {
                        //OTA未开启

                    }
                }
            }
        })

        mBleViewModel.otaControl.observeInFragment(this, Observer {
            if (it.isNotEmpty()) {
                it[mAddresses]?.let { item ->
                    when (item.second) {
                        0 -> {
                            if (dialog?.isShowing == true) {
                                mViewModel.uploadFile()
                            }
                        }
                        3 -> {

                        }
                        4 -> {
                            if (dialog?.isShowing == true) {
                                mViewModel.uploadComplete()
                            }
                        }
                    }
                }
            }
        })

        mViewModel.dataRateValue.observeInFragment(this, Observer {
            dialog?.let { item ->
                item.setMessage("OTA Upload...$it")
            }
        })
    }

    private fun setListener() {
        backButton.setOnClickListener {
            println("123-> exit SettingFragment")
            requireActivity().onBackPressed()
        }

        switchNotice.setOnClickListener {
            switchNotice.isSelected = !switchNotice.isSelected
            LocalDataDao.INSTANCE.setDisconnectNotice(switchNotice.isSelected, mAddresses)
        }

        switchAlarm.setOnClickListener {
            switchAlarm.isSelected = !switchAlarm.isSelected
            LocalDataDao.INSTANCE.setAlarm(switchAlarm.isSelected, mAddresses)
        }

        switchAlarmVibration.setOnClickListener {
            switchAlarmVibration.isSelected = !switchAlarmVibration.isSelected
            LocalDataDao.INSTANCE.setAlarmVibration(switchAlarmVibration.isSelected, mAddresses)
        }

        linear9.setOnClickListener {
            parentFragmentManager.beginTransaction()
                .setCustomAnimations(
                    R.anim.translate_into, R.anim.translate_out,
                    R.anim.translate_into_pop, R.anim.translate_out_exit
                )
                .add(
                    R.id.mainContent,
                    FAQSFragment.newInstance()
                )
                .addToBackStack("main")
                .commit()
        }

        linear7.setOnClickListener {
            val dialog = TempPreAlarmBottomDialog()
            dialog.setInitPosition(LocalDataDao.INSTANCE.getTempPreAlarm(mAddresses))
            dialog.showDialog(childFragmentManager)
            dialog.setOnItemSelectListener(object :
                TempPreAlarmBottomDialog.OnItemSelectListener {
                override fun onSelected(index: Int, indexString: String) {
                    preAlarmType.text = indexString
                    LocalDataDao.INSTANCE.setTempPreAlarm(index, mAddresses)
                }

            })

        }

        linear3.setOnClickListener {
            val dialog = ProbeAlarmBottomDialog()
            dialog.setSelectPosition(LocalDataDao.INSTANCE.getProbeAlarm1(mAddresses))
            dialog.showDialog(childFragmentManager)
            dialog.setOnItemSelectListener(object :
                ProbeAlarmBottomDialog.OnItemSelectListener {
                override fun onSelected(index: Int, indexString: String) {
                    probe_1.text = indexString
                    LocalDataDao.INSTANCE.setProbeAlarm1(index, mAddresses)
                }

            })
        }

        linear4.setOnClickListener {
            val dialog = ProbeAlarmBottomDialog()
            dialog.setSelectPosition(LocalDataDao.INSTANCE.getProbeAlarm2(mAddresses))
            dialog.showDialog(childFragmentManager)
            dialog.setOnItemSelectListener(object :
                ProbeAlarmBottomDialog.OnItemSelectListener {
                override fun onSelected(index: Int, indexString: String) {
                    probe_2.text = indexString
                    LocalDataDao.INSTANCE.setProbeAlarm2(index, mAddresses)
                }

            })
        }

        linear10.setOnClickListener {
            val connected = BleManager.getInstance().allConnectedDevice
            if (connected.isNotEmpty()) {
                val list = connected.filter { it.mac == mAddresses }
                if (list.isEmpty()) {
                    toast(R.string.text_connect_first)
                } else {
                    mViewModel.bluetoothGatt =
                        BleManager.getInstance().getBluetoothGatt(list.first())
                    val i = Intent()
                    i.type = "*/*"
                    i.action = Intent.ACTION_GET_CONTENT
                    currentOtaFileType = OtaFileType.APPLICATION
                    startActivityForResult(
                        Intent.createChooser(i, "Choose directory"),
                        FILE_CHOOSER_REQUEST_CODE
                    )
                }
            } else {
                toast(R.string.text_connect_first)
            }
        }
    }


    override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
        super.onActivityResult(requestCode, resultCode, data)
        if (resultCode == Activity.RESULT_OK) {
            when (requestCode) {
                FILE_CHOOSER_REQUEST_CODE -> {
                    val type = currentOtaFileType
                    val uri = data?.data

                    val filename: String? = try {
                        getFileName(uri)
                    } catch (e: Exception) {
                        ""
                    }

                    if (!hasOtaFileCorrectExtension(filename)) {
                        toast(R.string.text_incorrect_file)
                        return
                    }

                    if ((type == OtaFileType.APPLICATION)) {
                        prepareOtaFile(uri, OtaFileType.APPLICATION, filename)
                    } else {
                        toast(R.string.text_error)
                    }
                }
            }
        }

    }


    private fun prepareOtaFile(uri: Uri?, type: OtaFileType, filename: String?) {
        try {
            val inStream = requireActivity().contentResolver.openInputStream(uri!!)
            if (inStream == null) {
                toast(resources.getString(R.string.there_was_a_problem_while_preparing_the_file))
                return
            }
            val file = File(requireActivity().cacheDir, filename)
            val output: OutputStream = FileOutputStream(file)
            val buffer = ByteArray(4 * 1024)
            var read: Int
            while ((inStream.read(buffer).also { read = it }) != -1) {
                output.write(buffer, 0, read)
            }
            if ((type == OtaFileType.APPLICATION)) {
                appPath = file.absolutePath
                mViewModel.appPath=appPath
            }
            output.flush()
            //开始上传
            dialog = AlertDialog.Builder(requireContext())
                .setMessage("OTA Upload...")
                .setTitle("OTA Upload")
                .setNegativeButton(R.string.text_end) { _, _ ->
                    mViewModel.dfuMode("DISCONNECTION")
                }
                .show()
            mViewModel.startOTAUpload()
        } catch (e: IOException) {
            e.printStackTrace()
            toast(resources.getString(R.string.text_incorrect_file))
        }
    }


    private fun getFileName(uri: Uri?): String? {
        var result: String? = null
        if ((uri?.scheme == "content")) {
            val cursor = requireActivity().contentResolver.query(
                uri, null, null,
                null, null
            )
            cursor.use { c ->
                if (c != null && c.moveToFirst()) {
                    result = c.getString(c.getColumnIndex(OpenableColumns.DISPLAY_NAME))
                }
            }
        }
        if (result == null) {
            result = uri?.path
            val cut = result?.lastIndexOf('/')
            if (cut != -1) {
                result = result?.substring(cut!! + 1)
            }
        }
        return result
    }


    private fun hasOtaFileCorrectExtension(filename: String?): Boolean {
        return filename?.toUpperCase(Locale.getDefault())?.contains(".GBL")!!
    }


}